﻿using System;
using System.Collections.Generic;
using System.Linq;
using WHLRDF.Application.Model;
using System.Data;
using WHLRDF.ORM;
using Microsoft.AspNetCore.Http;
using WHLRDF.Application.BLL.WS;

namespace WHLRDF.Application.BLL
{
	
    public class UserService : SerivceBase, IUserService
    {
        #region 属性
        public const string User_No_Rule = "0001";
        public const string User_Extensions_Cache = "User_Extensions_Cache";
        #endregion
        #region 基本方法
        /// <summary>
        /// 查询所有
        /// </summary>
        public List<UserEntity> GetAll()
        {
            ICriterion criter = Expression.Eq("IsDeleted", false);
             return this.Query<UserEntity>(criter).ToList();
           
        }
		/// <summary>
		/// 获取单个实例的方法
		/// <param name="id">object类型</param>
		/// </summary>
        public UserEntity GetById(string id)
        {
            UserEntity entity = this.GetById<UserEntity>(id);
            if (entity != null&& WebSocketHelper.SocketConnectUsers!=null&& WebSocketHelper.SocketConnectUsers.Count>0)
            {
                entity.IsOnline =WebSocketHelper.SocketConnectUsers.Where(y => y.UserId == entity.UserId).FirstOrDefault() != null;
            }
           // BaseHelper.InitRegion(entity, entity.RegionId);
            return entity;
          
        }

		/// <summary>
		/// 保存方法
		/// <param name="entity">对象</param>
		/// <param name="strError">错误信息</param>
		/// </summary>
        public bool Save(UserEntity entity, ref string strError)
        {
            if (string.IsNullOrWhiteSpace(entity.Password))
            {
                entity.Password =MD5Helper.MD5Encrypt(ApplicationEnvironments.Site.DefaultPassword);
            }
            return Register(entity,ref strError,false);
        }
		/// <summary>
		/// 删除方法
		/// <param name="deleteKey">主键，如果字符串请将字符串列表用单引号将字符串用上,如（'aaa','bbb'）</param>
		/// <param name="strError">错误信息</param>
		/// </summary>
        public bool Delete(string deleteKey,ref string strError)
        {
            return  this.Delete<UserEntity>(deleteKey);
            
        }
		/// <summary>
		/// 分页查询方法
		/// <param name="grid">分页查询的相关参数</param>
		/// </summary>
        public LigerGrid ForGrid(LigerGrid grid)
        {
            ICriterion criter = Expression.Eq("IsDeleted", false);
            if (!string.IsNullOrEmpty(grid.keyWord))
            {
                criter = Expression.And(criter,

                           Expression.Like(new string[] {
                               UserEntity._PrimaryKeyName ,
                                UserEntity.__UserName,
                               UserEntity.__Email,
                                UserEntity.__Phone,
                                  UserEntity.__RealName

                           }, grid.keyWord)
                           );
            }
             return this.Query<UserEntity>( grid,criter);
        
        }
        #endregion

        #region 扩展方法
        /// <summary>
        /// 通过账号 手机 邮箱获取用户
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public UserEntity QueryByUserName(string userName)
        {
            ICriterion criterion = Expression.Eq(UserEntity.__IsDeleted, false);
            if (CheckValidHelper.IsEmail(userName))
            {
                criterion = Expression.And(criterion, Expression.Eq(UserEntity.__Email, userName));
            }
            else if (CheckValidHelper.IsPhone(userName))
            {
                criterion = Expression.And(criterion, Expression.Eq(UserEntity.__Phone, userName));
            }
            else {
                criterion = Expression.And(criterion, Expression.Eq(UserEntity.__UserName, userName));
            }
            return this.Query<UserEntity>(criterion).FirstOrDefault();
        }
        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        private bool IsExist(UserEntity entity)
        {

            var result = this.Query<UserEntity>(Expression.And(Expression.Eq(UserEntity.__IsDeleted, false),
                Expression.And(Expression.Not(Expression.Eq(UserEntity._PrimaryKeyName, entity.UserId)),
                Expression.Eq(UserEntity.__UserName, entity.UserName)))).FirstOrDefault();

            return result!=null;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public UserEntity GetByInfoId(string id,string token)
        {
            return this.GetByInfoId(id, token, false);
        }
        /// <summary>
        /// 获取单个实例的方法
        /// </summary>
        /// <param name="id">用户id</param>
        /// <param name="token">token</param>
        /// <param name="isPermission">是否登录</param>
        /// <returns></returns>
        public UserEntity GetByInfoId(string id,string token, bool isPermission)
        {
            UserEntity entity = this.GetById<UserEntity>(id);
            if (entity != null)
            {
                if (string.IsNullOrWhiteSpace(token))
                {
                    token = MD5Helper.MD5Encrypt(entity.UserId + entity.UserName + entity.Password + DateTime.Now.Ticks.ToString()).ToLower();
                    ApplicationEnvironments.DefaultSession.SetToken(token);
                }
                
                entity.Token = token;
                return GetUserExtensions(entity,token);
               
            }
            return entity;

        }
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="userName">账号（email,手机，账号）</param>
        /// <param name="Password">密码</param>
        /// <param name="strError">错误信息</param>
        /// <param name="oAuthCode"></param>
        /// <param name="oauthtoken"></param>
        /// <returns></returns>
        public UserEntity Login(string userName, string Password, ref string strError,ref string token, string oAuthCode = "", string oauthtoken = "")
        {
            if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(Password))
            {
                strError = "用户名或密码不正确！";
                return null; 
            }
            UserEntity entity=  this.QueryByUserName(userName);
            if (entity != null)
            {
                if (entity.Password.ToLower() != MD5Helper.MD5Encrypt(Password).ToLower())
                {
                    return null;
                }
                token = MD5Helper.MD5Encrypt(entity.UserId + entity.UserName + entity.Password + DateTime.Now.Ticks.ToString()).ToLower();
                entity.Token=token;
                entity =  GetUserExtensions(entity, token);
              
                //if (!BindOAuthUser(entity.UserId, oAuthCode, entity.UserAccount, oauthtoken, ref strError))
                //{
                //    return null;
                //}

            }
            return entity;
        }

        /// <summary>
        /// 自动登录
        /// </summary>
        /// <param name="userno">用户编号</param>
        /// <param name="userToken">加密字符串</param>
        /// <returns></returns>
        public UserEntity AutoLogin(string userId, string userToken, ref string strError)
        {
            if (string.IsNullOrEmpty(userId) ||string.IsNullOrEmpty(userToken))
            {
                return null;
            }
            ICriterion criter = Expression.And(
               Expression.Eq(UserEntity._PrimaryKeyName, userId),
               Expression.Eq(UserEntity.__IsDeleted, false)
               );
            //UserEntity entity = ApplicationEnvironments.DefaultSession.GetUser<UserEntity>();
            //if (entity != null)
            //{
            //    var newUserKey = MD5Helper.GetToken(entity.UserName + entity.Password).ToLower();
            //    if (newUserKey.Equals(userToken.ToLower()))
            //    {
            //        entity = GetUserExtensions(entity).Result;
            //        return entity;
            //    }
            //}
            return null;
        }

        /// <summary>
        /// 获取用户扩展信息 并缓存用户信息
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="token">令牌</param>
        /// <param name="isPermission">是否获取全新啊</param>
        /// <returns></returns>
        public UserEntity GetUserExtensions(UserEntity entity, string token, bool isPermission = true)
        {
            if (entity == null)
            {
                return null;
            }

            var relaUsers = AppHttpContext.GetSerivce<IRelationUserService>();
            entity.Roles = relaUsers.GetRelationByUserId<RoleEntity>(entity.UserId, RelationUserType.Role);

            var permissionService = AppHttpContext.GetSerivce<IPermissionService>();
           //entity.Groups = relaUsers.GetAll<GroupEntity>(entity.UserId, RelationUserType.Group);
            if (entity.UserId.Equals(ApplicationEnvironments.Site.AdminUser))
            {
                ICriterion criterion = Expression.And(Expression.Eq(PageEntity.__IsDisplay, true), Expression.And(Expression.Eq(PageEntity.__IsMenu, true), Expression.Eq(PageEntity.__IsDeleted, false)));
                entity.MyPageEntities = this.Query<PageEntity>(criterion, Order.Asc(PageEntity.__OrderNum));
            }
            if (isPermission|| entity.MyPageEntities==null|| entity.MyPageEntities.Count<=0)
            {
                entity.Permission = permissionService.GetMyPermission(entity);
                if (entity.Permission != null)
                {
                    entity.UnPermission = entity.Permission.Where(x => x.IsDisabled).ToList();
                    entity.Permission = entity.Permission.Where(x => !x.IsDisabled).ToList();
                    entity.Permission = entity.Permission.Where(x => (entity.UnPermission.Where(unp => unp.PageId == x.PageId)).FirstOrDefault() == null).ToList();//过滤掉不可访问权限
                    if (!entity.UserId.Equals(ApplicationEnvironments.Site.AdminUser))
                    {
                        string[] pageids = (from p in entity.Permission select p.PageId).ToArray();
                        if (pageids != null && pageids.Length > 0)
                        {

                            ICriterion criterion = Expression.And(Expression.In(PageEntity._PrimaryKeyName, pageids),
                               Expression.And(Expression.Eq(PageEntity.__IsDeleted, false),
                             Expression.And(Expression.Eq(PageEntity.__IsMenu, true), Expression.Eq(PageEntity.__IsDisplay, true)))
                                );

                            entity.MyPageEntities = this.Query<PageEntity>(criterion, Order.Asc(PageEntity.__OrderNum));
                        }
                    }
                }
            }
            CacheService.Add(ApplicationEnvironments.Site.UserCacheKey + token, entity, TimeSpan.FromMinutes(ApplicationEnvironments.Site.SessionTimeout), true);
            return entity;




        }
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="oldPwd"></param>
        /// <param name="newPwd"></param>
        /// <returns></returns>
        public virtual AjaxResult ChangePwd(string oldPwd, string newPwd)
        {
           UserEntity entity  = this.GetById<UserEntity>(ApplicationEnvironments.DefaultSession.UserId);
           if (entity != null)
           {
               if (entity.Password.ToLower() == oldPwd.ToLower())
               {
                   entity.Password = newPwd;
               }
               else
               {
                   return AjaxResult.Error("密码不匹配，无法更新");
               }
              //  this.SaveOrUpdate<UserEntity>(entity);
            }
            return AjaxResult.Success();
        }

        /// <summary>
        /// 判断用户名是否不存在
        /// </summary>
        /// <param name="UserId">用户id</param>
        /// <param name="userAccount">用户账户</param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool ChkUserName(string userid,string userName,ref string strError) {
            ICriterion criter = Expression.And(
            Expression.Not( Expression.Eq(UserEntity._PrimaryKeyName, userid)),
            Expression.And(Expression.Eq(UserEntity.__UserName, userName),
             Expression.Eq(UserEntity.__IsDeleted, false))
             );
           var entity=  this.Query<UserEntity>(criter).FirstOrDefault();
            return entity==null;
        }
        /// <summary>
        /// 判断Email是否不存在
        /// </summary>
        /// <param name="UserId">用户id</param>
        /// <param name="email">邮箱账号</param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool ChkUserEmail(string userid, string email, ref string strError)
        {
            ICriterion criter = Expression.And(
            Expression.Not(Expression.Eq(UserEntity._PrimaryKeyName, userid)),
            Expression.And(Expression.Eq(UserEntity.__Email, email),
             Expression.Eq(UserEntity.__IsDeleted, false))
             );
            var entity = this.Query<UserEntity>(criter).FirstOrDefault();
            return entity == null;
        }

        /// <summary>
        /// 判断Phone是否不存在
        /// </summary>
        /// <param name="UserId">用户id</param>
        /// <param name="Phone">手机号码</param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool ChkUserPhone(string userid, string phone, ref string strError)
        {
            ICriterion criter = Expression.And(
            Expression.Not(Expression.Eq(UserEntity._PrimaryKeyName, userid)),
            Expression.And(Expression.Eq(UserEntity.__Phone, phone),
             Expression.Eq(UserEntity.__IsDeleted, false))
             );
            var entity = this.Query<UserEntity>(criter).FirstOrDefault();
            return entity == null;
        }

        /// <summary>
        /// 新用户注册
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="strError"></param>
        /// <param name="isRegister"></param>
        /// <param name="oAuthCode"></param>
        /// <param name="oauthtoken"></param>
        /// <returns></returns>
        public bool Register(UserEntity entity, ref string strError, bool isRegister = true,string verifycode="", string oAuthCode = "", string oauthtoken = "")
        {
            if (!CheckValidHelper.CheckVaild(entity, ref strError))
            {
                return false;
            }
            if (isRegister)
            {
                if (string.IsNullOrWhiteSpace(verifycode))
                {
                    strError = "验证码不正确";
                    return false;
                }
                object oldCode = CacheService.GetCache(MD5Helper.GetToken((ConfigHelper.EMAIL_SEND_ACTIVE_VER_CODE + entity.Email + verifycode).ToLower()).ToLower());
                if (oldCode != null && !verifycode.ToLower().Equals(oldCode.ToString().ToLower()))
                {
                    strError = "验证码不正确";
                    return false;
                }
            }
            if (!ChkUserName(entity.UserId, entity.UserName, ref strError))
            {
                strError = "用户名已存在，请重新输入用户名";
                return false;
            }
            if (!ChkUserEmail(entity.UserId, entity.Email, ref strError))
            {
                strError = "邮箱已存在，请重新输入邮箱";
                return false;
            }
            if (!ChkUserPhone(entity.UserId, entity.Phone, ref strError))
            {
                strError = "手机已存在，请重新输入手机";
                return false;
            }

            if (string.IsNullOrWhiteSpace(entity.UserId))
            {
                entity.UserId = SerialService.CreateSerialNo(User_No_Rule, null, ref strError);
            }
            if (isRegister)
            {
                entity.UserType =Convert.ToInt16(UserType.Regiter.GetHashCode());
                
                entity.Password = MD5Helper.MD5Encrypt(entity.Password);
            }
            if (this.SaveOrUpdate<UserEntity>(entity, ref strError))
            {
               return BindOAuthUser(entity.UserId,oAuthCode,entity.UserName,oauthtoken,ref strError);
            }
            return false;
          

        }

        public bool ResetPwd(string userids, ref string strError) {
            if (!string.IsNullOrEmpty(userids))
            {
                //using (var tran = SessionFactory.BeginTransaction())
                //{
                //    try
                //    {
                //        SessionFactory.ExecuteUpdate("update UserEntity set "+ UserEntity.__Password + "='" + MD5Helper.MD5Encrypt(ConfigHelper.DefaultPassword) + "' where "+ UserEntity._PrimaryKeyName +" in ("+userids+")");
                //        SessionFactory.Commit();
                //    }
                //    catch (Exception ex)
                //    {

                //        SessionFactory.Rollback();
                //        throw ex;
                //    }

                //}
                //SessionFactory.Flush();;
            }
            return true;
        }
        public bool ChangePwd(string userName, string pwd, string repwd,string token,string vercode,string mailvercode, ref string strError) {
            if (string.IsNullOrWhiteSpace(userName))
            {
                strError = "用户名为空";
                return false;
            }
            string oldVerCode = AppHttpContext.Current.Session.Get<string>(ConfigHelper.RESET_PASSWORD_SEND_VER_CODE);
            if (string.IsNullOrWhiteSpace(oldVerCode)||!oldVerCode.ToLower().Equals(vercode))
            {
                strError= "验证码不正确！";
                return false;
            }
            if (string.IsNullOrEmpty(pwd) || !pwd.Equals(repwd))
            {
                strError = "密码为空或者确认密码与密码不匹配，请确认后在输入！";
                return false;
            }
            var entity= this.QueryByUserName(userName);
            if (entity == null)
            {
                strError = " 账号不存在！";
                return false;
            }
            string newtoken = MD5Helper.GetToken(entity.UserId + entity.Password + ConfigHelper.RESET_PASSWORD_SEND_VER_CODE + mailvercode.ToLower()).ToLower();
            if (newtoken.Equals(token.ToLower()))
            {
                var oldCode = CacheService.GetCache(newtoken).ToString();
                if (!string.IsNullOrWhiteSpace(oldCode) && mailvercode.Equals(oldCode))
                {
                    entity.Password = MD5Helper.MD5Encrypt(pwd);
                    entity.LastModifyDate = DateTime.Now;
                    return this.SaveOrUpdate<UserEntity>(entity, ref strError);
                }
            }
            strError = "邮箱验证码不正确！";
            return false;

        }


        public bool BindOAuthUser(string userid, string oauthCode, string userName,
            string oauthToken, ref string strError)
        {
            if (string.IsNullOrWhiteSpace(oauthCode) || string.IsNullOrWhiteSpace(oauthToken))
            {
                return true;
            }
            SortedDictionary<string, string> dicParam = new SortedDictionary<string, string>();
            dicParam.Add("userid", userid.ToString());
            dicParam.Add("oauthcode", oauthCode);
            dicParam.Add("username", userName);
            dicParam.Add("oauthtoken", oauthToken);
            dicParam.Add("token",MD5Helper.GetToken(dicParam));
            string strResult="";
            //HttpHelper.SendReq(string.Format(ConfigHelper.OAuthApiUrl,"bind"), dicParam, "utf-8", ref strResult);
            if (!string.IsNullOrWhiteSpace(strResult))
            {
                AjaxResult result = JSONHelper.FromJson<AjaxResult>(strResult);
                strError = result.Message;
                return !result.IsSuccess;
            }
            strError = strResult;
            return false;
        }

        /// <summary>
        /// 通过关键字搜索用户
        /// </summary>
        /// <param name="ligerGrid"></param>
        /// <returns></returns>
        public LigerGrid GetUsersByName(LigerGrid ligerGrid)
        {
            ICriterion criter =  Expression.Eq(UserEntity.__IsDeleted, false);
            if (!string.IsNullOrWhiteSpace(ligerGrid.keyWord))
            {
                criter = Expression.And(criter,
                Expression.Like(
                    new string[] {
               UserEntity.__Phone,
               UserEntity.__Email,
                UserEntity.__RealName,
                 UserEntity.__UserName,
                   UserEntity._PrimaryKeyName
               }, ligerGrid.keyWord));
            }
            if (string.IsNullOrWhiteSpace(ligerGrid.sortName))
            {
                ligerGrid.sortName = UserEntity._PrimaryKeyName;
                ligerGrid.sortOrder = "asc";
            }
            Expression.And(criter,Expression.Not(Expression.Eq(UserEntity._PrimaryKeyName,ApplicationEnvironments.DefaultSession.UserId)));
            ligerGrid= this.Query<UserEntity>(ligerGrid,criter);
            if (ligerGrid != null && ligerGrid.Rows != null)
            {
                List<UserEntity> userEntities = (List<UserEntity>)ligerGrid.Rows;
                if (userEntities.Count > 0 && WebSocketHelper.SocketConnectUsers!=null && WebSocketHelper.SocketConnectUsers.Count>0)
                {
                    userEntities.ForEach(x =>
                    {
                        x.IsOnline = WebSocketHelper.SocketConnectUsers.Where(y=>y.UserId==x.UserId).FirstOrDefault()!=null;
                    });
                    ligerGrid.Rows = from x in userEntities select new { UserId = x.UserId, UserName = x.UserName, RealName = x.RealName, Phone = x.Phone,Email=x.Email };
                }
            }
            return ligerGrid;
        }

        /// <summary>
        /// 通过用户名  邮件 手机号 或者账号获取用户
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public UserEntity GetUserByAccount(string account)
        {
            if (string.IsNullOrWhiteSpace(account))
            {
                return null;
            }
            ICriterion criter = Expression.Eq(UserEntity.__IsDeleted, false);
            criter = Expression.And(criter,
                Expression.Or(Expression.Eq(UserEntity.__UserName, account),
                 Expression.Or(Expression.Eq(UserEntity.__Email, account),
                 Expression.Or(Expression.Eq(UserEntity.__Phone, account),Expression.Eq(UserEntity._PrimaryKeyName,account)))));
            return this.Select<UserEntity>(criter);
           
        }

        public bool Import(IFormFile file, ref string strError)
        {
            var lstAll = OfficeHelper.ImportExcel<UserEntity>(file);
            return true;
        }

        public byte[] Export(ref string strError)
        {
            var lstAll= this.GetAll();

            return OfficeHelper.OutputExcel<UserEntity>(lstAll);
        }
       
    
        #endregion

    }
}
